#!/usr/bin/env python3
# Copyright (c) 2019-2020 Windy Albert


from ctypes import BigEndianStructure
import keyTree

from addrBTC import *
from addrETH import *
from addrDOGE import *
from addrFIL import *
from addrTRX import *
from addrBNB import *

import os
import json
import sys
import getpass
import time


def usage():
    print("Make by Windy Albert")
    print("Usage:")
    print("    ./genAddr_with_xpub xxx.pub path.conf  # Generate the coin address with the pubkey.")
    # print("    ./genAddr_with_xpub all                # Generate all coin address with the pubkey.")

def main():
    addrConstuct={}
    addrConstuct["0\'/0\'"] = addrBTC_p2pkh
    addrConstuct["0\'/1\'"] = addrBTC_p2wpkh
    addrConstuct["0\'/2\'"] = addrBTC_p2wpkh_p2sh
    addrConstuct["0\'/3\'"] = addrBTC_p2wsh
    addrConstuct["0\'/4\'"] = addrBTC_p2wsh_p2sh

    addrConstuct["60\'/0\'"] = addrETH
    addrConstuct["3\'/0\'"] = addrDOGE
    addrConstuct["461\'/0\'"] = addrFIL
    addrConstuct["195\'/0\'"] = addrTRX
    addrConstuct["714\'/0\'"] = addrBNB
    
    pubkeys = {}

    if len(sys.argv) != 3 :
        usage()
        return

    # if sys.argv[1] == "all" :
    #     for dirpath, dirnames, filenames in os.walk("WIF/*/COLD"):
    #         for file in filenames:
    #             rfile = open(os.path.join(dirpath, file),'r')
    #             data = rfile.read()
    #             rfile.close()
    #             pubkey = json.loads(data)
    #             pubkeys[pubkey["path"]] = pubkey["xpub"]

    # else :
    xpubfile = sys.argv[1]
    pathfile = sys.argv[2]
    if not os.path.exists(xpubfile) :
        print("Error: The file "+xpubfile+" is NOT exist ...")
        return
    if not os.path.exists(pathfile) :
        print("Error: The file "+pathfile+" is NOT exist ...")
        return
        
    rfile = open(os.path.join(xpubfile),'r')
    data = rfile.read()
    rfile.close()
    pubkey = json.loads(data)
    pubkeys[pubkey["path"]] = pubkey["xpub"]

    file1 = open(pathfile,'r')
    data = file1.read()
    ptree = json.loads(data)
    file1.close()

    tree = keyTree("")
    # write result to file
    file = open("addr.list",'w')
    file.flush()    
    address = "########################### Address List ###########################\n\n"

    purposelist = ptree["child"]
    for purpose in purposelist:
        coinlist = purpose["child"]
        for coin in coinlist:
            if sys.argv[1] == "all" :
                print_line("Coin : "+coin["coin"],COLOR_RED)
            accountlist = coin["child"]
            for account in accountlist:
                changelist=account["child"]

                for change in changelist:
                    wiflist=change["child"]
                    pa = "m/"+purpose["path"] + "/" + coin["path"] +"/" + account["path"] + "/" + change["path"]

                    if not pa in pubkeys :
                        continue

                    change_pubkey ={"path":pa,"xpub":pubkeys[pa]} 
                    walletObj = addrConstuct[coin["path"]+"/"+account["path"]]("")

                    print('{:23s}'.format(change_pubkey["path"])+": "+COLOR_GREEN+change_pubkey["xpub"]+COLOR_NONE)
                    # addres = ""
                    for wif in wiflist:
                        xpub,pubkey = tree.getChildpubKey(change_pubkey,wif["path"])
                        addr = walletObj.getAddr(pubkey)

                        address += '{:23s}'.format(coin["coin"]+"_"+account["account"]+"_"+change["path"] +"_"+wif["path"])
                        address += (": "+addr+"\n")

                        name ='{:23s}'.format( coin["coin"]+"_"+ account["account"] +"_addr_" + change["path"] +"_"+wif["path"] )
                        print( name+": "+COLOR_GREEN+addr+COLOR_NONE)
                    address += "\n"


    address += "####################################################################\n"
    file.write(address)
    file.close()

    sha256 = hashlib.new('sha256',address.encode('utf-8')).hexdigest()
    os.rename("addr.list","Waddress_xpub"+ time.strftime("_%y%m%02d_", time.localtime()) +sha256[0:6])

if __name__ == '__main__':
    main()